<template>
    <div class="role-container">
        <!-- 搜索区域 -->
        <el-card class="search-card">
            <el-form :model="searchForm" :inline="true" class="search-form">
                <el-form-item label="角色">
                    <el-input v-model="searchForm.roleName" placeholder="请输入角色名称/编号" clearable />
                </el-form-item>
                <el-form-item label="状态">
                    <el-select v-model="searchForm.roleState" placeholder="请选择状态" clearable>
                        <el-option label="启用" :value="1" />
                        <el-option label="停用" :value="0" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleSearch">查询</el-button>
                    <el-button @click="handleReset">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <!-- 操作按钮区域 -->
        <el-card class="action-card">
            <el-button type="primary" @click="handleAdd">新增</el-button>
            <el-button type="success" @click="handleBatchEnable"
                :disabled="multipleSelection.length === 0">批量启用</el-button>
            <el-button type="warning" @click="handleBatchDisable"
                :disabled="multipleSelection.length === 0">批量停用</el-button>
            <el-button type="danger" @click="handleBatchDelete"
                :disabled="multipleSelection.length === 0">批量删除</el-button>
        </el-card>

        <!-- 角色列表表格 -->
        <el-card class="table-card">
            <el-table :data="roleTableData" style="width: 100%" @selection-change="handleSelectionChange"
                height="500px">
                <el-table-column type="selection" width="55" />
                <el-table-column type="index" label="序号" width="80" />
                <el-table-column property="roleName" label="角色名称" width="200" />
                <el-table-column property="userCount" label="用户人数" width="120" />
                <el-table-column property="roleSort" label="排序" width="80" />
                <el-table-column property="roleState" label="状态" width="80">
                    <template #default="{ row }">
                        <el-tag :type="row.roleState === 1 ? 'success' : 'danger'">
                            {{ row.roleState === 1 ? '启用' : '停用' }}
                        </el-tag>
                    </template>
                </el-table-column>
                <el-table-column property="roleNote" label="备注" min-width="150" />
                <el-table-column label="操作" width="160" fixed="right">
                    <template #default="{ row }">
                        <el-button link type="primary" size="small" @click="handleEdit(row)">编辑授权</el-button>
                        <el-button link type="danger" size="small" @click="handleDelete(row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>

            <!-- 分页组件 -->
            <el-pagination v-model:current-page="pagination.pageIndex" v-model:page-size="pagination.pageSize"
                :page-sizes="[10, 20, 50, 100]" :total="pagination.total"
                layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
                @current-change="handleCurrentChange" style="margin-top: 20px; text-align: right;" />
        </el-card>

        <!-- 新增/编辑对话框 -->
        <el-dialog v-model="dialogVisible" :title="dialogTitle" width="800px" @close="handleDialogClose">
            <el-form ref="roleFormRef" :model="roleForm" :rules="roleFormRules" label-width="100px">
                <el-row :gutter="20">
                    <el-col :span="12">
                        <el-form-item label="角色名称 *" prop="roleName">
                            <el-input v-model="roleForm.roleName" placeholder="请输入角色名称" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="排序" prop="roleSort">
                            <el-input-number v-model="roleForm.roleSort" :min="0" style="width: 100%" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20">
                    <el-col :span="12">
                        <el-form-item label="状态" prop="roleState">
                            <el-radio-group v-model="roleForm.roleState">
                                <el-radio :label="1">启用</el-radio>
                                <el-radio :label="0">停用</el-radio>
                            </el-radio-group>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-form-item label="备注" prop="roleNote">
                    <el-input v-model="roleForm.roleNote" type="textarea" :rows="3" placeholder="请输入备注" />
                </el-form-item>
                <el-form-item label="权限 *" prop="permissions">
                    <el-tree ref="permissionTreeRef" :data="permissionTreeData"
                        :props="{ children: 'children', label: 'label' }" show-checkbox node-key="id"
                        :default-expand-all="true" :check-strictly="false"
                        style="width: 100%; border: 1px solid #dcdfe6; border-radius: 4px; padding: 10px; max-height: 300px; overflow-y: auto;" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="handleSave">确定</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox, type FormRules, type FormInstance } from 'element-plus'
import myaxios from "@/http/MyAxios"

// 搜索表单数据
const searchForm = reactive({
    roleName: '',
    roleState: null
})

// 角色表格数据
const roleTableData = ref<any[]>([])

// 权限树形数据
const permissionTreeData = ref<any[]>([])
// 将任意结构映射为 { id, label, children }
const mapToTreeOptions = (nodes: any[]): any[] => {
    return (nodes || []).map((n: any) => ({
        id: n.id ?? n.permissionId ?? n.value,
        label: n.label ?? n.permissionName ?? n.name,
        children: mapToTreeOptions(n.children || [])
    }))
}

// 仅保留属于叶子节点的已选ID，避免父节点导致整棵子树全选
const collectLeafIdsFor = (ids: Array<string | number>, tree: any[]): Array<string | number> => {
    const idSet = new Set(ids.map((x: any) => (typeof x === 'number' ? x : String(x))))
    const leafSet: any = new Set()
    const dfs = (nodes: any[]) => {
        for (const n of nodes || []) {
            const hasChildren = n.children && n.children.length
            const key = typeof n.id === 'number' ? n.id : String(n.id)
            if (!hasChildren && idSet.has(key)) {
                leafSet.add(n.id)
            }
            if (hasChildren) dfs(n.children)
        }
    }
    dfs(tree || [])
    return Array.from(leafSet)
}

// 获取权限菜单树（与菜单保持同步）
const getPermissionTree = (): Promise<void> => {
    return myaxios({ url: '/api/Permission/GetParentPermissionOptions', method: 'get' })
        .then(res => {
            const raw = res.data || []
            if (Array.isArray(raw) && (raw.length === 0 || ('id' in raw[0] || 'label' in raw[0]))) {
                permissionTreeData.value = raw
            } else {
                permissionTreeData.value = mapToTreeOptions(raw)
            }
        })
        .catch(err => {
            console.log('获取权限菜单失败:', err)
        })
}

// 分页数据
const pagination = reactive({
    pageIndex: 1,
    pageSize: 12,
    total: 0
})

// 多选数据
const multipleSelection = ref<any[]>([])

// 对话框相关
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)
const roleFormRef = ref<FormInstance>()
const permissionTreeRef = ref()

// 角色表单数据
const roleForm = reactive<{ roleId: number | null; roleName: string; roleSort: number; roleState: number; roleNote: string; permissions: any[] }>({
    roleId: null,
    roleName: '',
    roleSort: 0,
    roleState: 1,
    roleNote: '',
    permissions: []
})

// 表单验证规则
const roleFormRules: FormRules = {
    roleName: [
        { required: true, message: '请输入角色名称', trigger: 'blur' }
    ],
    permissions: [
        { required: true, message: '请选择权限', trigger: 'change' }
    ]
}

// 获取角色列表
const getRoleList = () => {
    myaxios({
        url: "/api/Role/GetRoleList",
        method: "get",
        params: {
            pageIndex: pagination.pageIndex,
            pageSize: pagination.pageSize,
            ...searchForm
        }
    })
        .then(res => {
            if (res.data.code === 200) {
                roleTableData.value = res.data.data.data || []
                pagination.total = res.data.total || 0
            } else {
                ElMessage.error(res.data.message || '获取数据失败')
            }
        })
        .catch(err => {
            console.log(err)
            ElMessage.error('获取数据失败')
        })
}
// 搜索
const handleSearch = () => {
    pagination.pageIndex = 1
    getRoleList()
}

// 重置搜索
const handleReset = () => {
    searchForm.roleName = ''
    searchForm.roleState = null
    pagination.pageIndex = 1
    getRoleList()
}

// 分页大小改变
const handleSizeChange = (size: number) => {
    pagination.pageSize = size
    pagination.pageIndex = 1
    getRoleList()
}

// 当前页改变
const handleCurrentChange = (page: number) => {
    pagination.pageIndex = page
    getRoleList()
}

// 多选变化
const handleSelectionChange = (selection: any[]) => {
    multipleSelection.value = selection
}

// 重置表单
const resetRoleForm = () => {
    roleForm.roleId = null
    roleForm.roleName = ''
    roleForm.roleSort = 0
    roleForm.roleState = 1
    roleForm.roleNote = ''
    roleForm.permissions = []
    // 清空权限树选择
    permissionTreeRef.value?.setCheckedKeys([])
}

// 关闭对话框
const handleDialogClose = () => {
    roleFormRef.value?.resetFields()
    resetRoleForm()
}

// 新增角色
const handleAdd = () => {
    dialogTitle.value = '新增角色'
    isEdit.value = false
    resetRoleForm()
    dialogVisible.value = true
    // 加载权限树
    getPermissionTree()
}

// 保存角色
const handleSave = () => {
    // 获取选中的权限
    const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []
    const halfCheckedKeys = permissionTreeRef.value?.getHalfCheckedKeys() || []
    roleForm.permissions = [...checkedKeys, ...halfCheckedKeys]

    if (roleForm.permissions.length === 0) {
        ElMessage.warning('请选择权限')
        return
    }

    roleFormRef.value?.validate((valid) => {
        if (valid) {
            const url = isEdit.value ? '/api/Role/UpdateRole' : '/api/Role/CreateRole'
            const method = 'post'

            // 后端需要的结构: permissionIds: number[]
            const permissionIds = (roleForm.permissions || []).map((x: any) => Number(x)).filter((x: any) => !isNaN(x))
            const basePayload: any = {
                roleName: roleForm.roleName,
                roleSort: roleForm.roleSort,
                roleState: roleForm.roleState,
                roleNote: roleForm.roleNote,
                permissionIds
            }
            const payload = isEdit.value ? { ...basePayload, roleId: roleForm.roleId } : basePayload

            myaxios({
                url: url,
                method: method,
                data: payload
            })
                .then(res => {
                    if (res.data.code === 200) {
                        ElMessage.success(res.data.message || '保存成功')
                        dialogVisible.value = false
                        getRoleList()
                    } else {
                        ElMessage.error(res.data.message || '保存失败')
                    }
                })
                .catch(err => {
                    console.log(err)
                    ElMessage.error('保存失败')
                })
        } else {
            ElMessage.warning('请填写必填项')
        }
    })
}

// 编辑角色
const handleEdit = async (row: any) => {
    dialogTitle.value = '编辑角色'
    isEdit.value = true
    resetRoleForm()
    dialogVisible.value = true
    // 加载权限树
    await getPermissionTree()
    // 反填表单数据
    roleForm.roleId = row.roleId || null
    roleForm.roleName = row.roleName || ''
    roleForm.roleSort = row.roleSort || 0
    roleForm.roleState = row.roleState !== undefined ? row.roleState : 1
    roleForm.roleNote = row.roleNote || ''

    // 获取角色权限并设置选中状态
    if (row.roleId) {
        myaxios({
            url: `/api/Role/GetRolePermissionIds`,
            method: "get",
            params: { roleId: row.roleId }
        })
            .then(res => {
                if (res.data.code === 200) {
                    const permissions = res.data.data || []
                    roleForm.permissions = permissions
                    // 仅勾选叶子，避免父节点导致所有子节点全选
                    const leafIds = collectLeafIdsFor(permissions, permissionTreeData.value || [])
                    // 先清空再设置，避免残留
                    permissionTreeRef.value?.setCheckedKeys([], true)
                    permissionTreeRef.value?.setCheckedKeys(leafIds, true)
                }
            })
            .catch(err => {
                console.log(err)
            })
    }
}

// 删除单个角色
const handleDelete = (row: any) => {
    ElMessageBox.confirm(
        '确认删除这个角色信息吗?',
        '警告',
        {
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning',
        }
    )
        .then(() => {
            myaxios({
                url: "/api/Role/DeleteRole",
                method: "delete",
                params: { roleId: row.roleId }
            })
                .then(res => {
                    if (res.data.code === 200) {
                        getRoleList()
                        ElMessage.success(res.data.message || '删除成功')
                    } else {
                        ElMessage.error(res.data.message || '删除失败')
                    }
                })
                .catch(err => {
                    console.log(err)
                    ElMessage.error('删除失败')
                })
        })
        .catch(() => {
            ElMessage({
                type: 'info',
                message: '已取消',
            })
        })
}

// 批量删除
const handleBatchDelete = () => {
    if (multipleSelection.value.length === 0) {
        ElMessage.warning('请选择要删除的角色')
        return
    }
    ElMessageBox.confirm(
        '确认删除这些角色信息吗?',
        '警告',
        {
            confirmButtonText: '确认',
            cancelButtonText: '取消',
            type: 'warning',
        }
    )
        .then(() => {
            const roleIds = multipleSelection.value.map((x: any) => x.roleId)
            myaxios({
                url: "/api/Role/DeleteRoles",
                method: "post",
                data: {
                    ids: roleIds
                }
            })
                .then(res => {
                    if (res.data.code === 200) {
                        getRoleList()
                        ElMessage.success(res.data.message || '删除成功')
                    } else {
                        ElMessage.error(res.data.message || '删除失败')
                    }
                })
                .catch(err => {
                    console.log(err)
                    ElMessage.error('删除失败')
                })
        })
        .catch(() => {
            ElMessage({
                type: 'info',
                message: '已取消',
            })
        })
}

// 批量启用
const handleBatchEnable = () => {
    if (multipleSelection.value.length === 0) {
        ElMessage.warning('请选择要启用的角色')
        return
    }
    const roleIds = multipleSelection.value.map((x: any) => x.roleId)
    myaxios({
        url: "/api/Role/SetRolesState",
        method: "post",
        data: {
            ids: roleIds,
            state: 1
        }
    })
        .then(res => {
            if (res.data.code === 200) {
                getRoleList()
                ElMessage.success(res.data.message || '启用成功')
            } else {
                ElMessage.error(res.data.message || '启用失败')
            }
        })
        .catch(err => {
            console.log(err)
            ElMessage.error('启用失败')
        })
}

// 批量停用
const handleBatchDisable = () => {
    if (multipleSelection.value.length === 0) {
        ElMessage.warning('请选择要停用的角色')
        return
    }
    const roleIds = multipleSelection.value.map((x: any) => x.roleId)
    myaxios({
        url: "/api/Role/SetRolesState",
        method: "post",
        data: {
            ids: roleIds,
            state: 0
        }
    })
        .then(res => {
            if (res.data.code === 200) {
                getRoleList()
                ElMessage.success(res.data.message || '停用成功')
            } else {
                ElMessage.error(res.data.message || '停用失败')
            }
        })
        .catch(err => {
            console.log(err)
            ElMessage.error('停用失败')
        })
}

// 页面加载时获取数据
onMounted(() => {
    getRoleList()
})
</script>

<style scoped>
.role-container {
    padding: 20px;
}

.search-card,
.action-card,
.table-card {
    margin-bottom: 20px;
}

.search-form .el-form-item {
    margin-bottom: 0;
}

.el-input,
.el-select {
    width: 200px;
}
</style>